#define 演示全部功能

using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models;
using SwaggerDemo.Core;
using System;
using System.IO;
using System.Reflection;
using System.Text;
using Swashbuckle.AspNetCore.Filters;

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();

#region ========================== Swagger 配置 ==========================

// 通用配置，参数项包括：项目标题、文档说明、项目版本号
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(option => {
  var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
  var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);

  option.IncludeXmlComments(xmlPath, true);

  //// 单API版本
  //option.SwaggerDoc("v1", new OpenApiInfo
  //{
  //  Title = "Awesome Project 接口文档",
  //  Version = "v2.0.1",
  //  Description = "这里是文档的详细说明..."
  //});

  // 多API版本
  foreach (FieldInfo field in typeof(ApiVersion).GetFields()) {
    option.SwaggerDoc(field.Name, new OpenApiInfo() {
      Title = "Awesome Project 接口文档",
      Version = field.Name,
      Description = "这里是文档的详细说明..."
    });
  }

#if 演示全部功能
  option.OrderActionsBy(o => o.RelativePath);
  // 指定哪些响应头应该显示在Swagger文档中，使开发人员了解API的响应头信息。
  option.OperationFilter<AddResponseHeadersFilter>();
  //将身份验证/授权需求追加到API操作描述的摘要中，以提醒开发人员该操作需要认证和授权。
  option.OperationFilter<AppendAuthorizeToSummaryOperationFilter>();
  // 自定义Swagger文档中每个操作所需的安全需求，从而告知开发人员该操作的安全性要求。
  option.OperationFilter<SecurityRequirementsOperationFilter>();
  // 自定义过滤器
  option.OperationFilter<SwaggerFilter>();
#endif

  option.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme() {
    In = ParameterLocation.Header,
    Name = "Authorization",
    Type = SecuritySchemeType.ApiKey,
    Scheme = "Bearer",
    BearerFormat = "JWT",
    Description = "<b>JWT Authorization header using the Bearer scheme.</b> \r\n\r\n Example: \"Bearer  {token}\"",
  });

  option.AddSecurityRequirement(new OpenApiSecurityRequirement {
    {
      new OpenApiSecurityScheme {
        Reference = new OpenApiReference {
          Id = "Bearer",
          Type = ReferenceType.SecurityScheme
        }
      },
      Array.Empty<string>()
    }
  });
});

#endregion

#region ========================== JwtBearer 配置 ==========================

builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options => {
  options.TokenValidationParameters = new TokenValidationParameters {
    ValidateIssuer = true,
    ValidateAudience = true,
    ValidateLifetime = true,
    ValidateIssuerSigningKey = true,
    ValidIssuer = builder.Configuration["JwtOptions:Issuer"],
    ValidAudience = builder.Configuration["JwtOptions:Audience"],
    IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["JwtOptions:SecretKey"]!))
  };
});

#endregion

var app = builder.Build();
app.UseRouting();
app.MapControllers();

// 引用Swagger
if (app.Environment.IsDevelopment()) {
  app.UseDeveloperExceptionPage();
  app.UseSwagger();
  // 单API版本
  //app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "Awesome Project Beta"));

  // 多API版本
  app.UseSwaggerUI(c => {
    foreach (FieldInfo field in typeof(ApiVersion).GetFields()) {
      c.SwaggerEndpoint($"/swagger/{field.Name}/swagger.json", $"{field.Name}");
    }
  });
}

// 引用授权验证
app.UseAuthentication();
app.UseAuthorization();
app.Run();